package com.by.toolkit.utils;

import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 描述：直接使用option会好些
 *
 * @author liujun
 * @date 2023年06月17 11:17 AM
 */
public class ByIfNotNullUtil {


    private ByIfNotNullUtil() {

    }

    /**
     * @param object    对象
     * @param notNullSupplier 不为空时执行
     * @param defaultVal   为空时返回
     * @return 返回
     */
    public static <T> T getIfNotNull(Object object, Supplier<T> notNullSupplier, T defaultVal) {
        if (Objects.nonNull(object)) {
            return notNullSupplier.get();
        } else {
            return defaultVal;
        }
    }

    /**
     * @param object     对象
     * @param notNullSupplier  非空执行
     * @param nullSupplier 空执行
     * @return 返回
     */
    public static <T> T getIfNotNullOrElse(Object object, Supplier<T> notNullSupplier, Supplier<T> nullSupplier) {
        if (Objects.nonNull(object)) {
            return notNullSupplier.get();
        } else {
            return nullSupplier.get();
        }
    }


    /**
     * 注意： doIfNotNull(set, set::size)会抛空指针异常，需改为
     *       doIfNotNull(set, ()->set.size())
     * @param object    对象
     * @param notNullRunnable 非空时执行
     */
    public static void doIfNotNull(Object object, ByRunnable notNullRunnable) {
        if (Objects.nonNull(object)) {
            notNullRunnable.run();
        }
    }

    public  static <T> void doIfNotNull(T t, Consumer<T> notNullConsumer) {
        if (Objects.nonNull(t)) {
            notNullConsumer.accept(t);
        }
    }

    /**
     * @param object     对象
     * @param notNullRunnable  非空执行
     * @param nullRunnable 空执行
     */
    public static void doIfNotNullOrElse(Object object, ByRunnable notNullRunnable, ByRunnable nullRunnable) {
        if (Objects.nonNull(object)) {
            notNullRunnable.run();
        } else {
            nullRunnable.run();
        }
    }


    /**
     * @param object          判断对象
     * @param notNullSupplier 非空执行
     * @param nullSupplier    空执行
     * @param <T>             返回
     * @return supplier.get
     */
    public static <T> T getIfNotNullOrElseThrow(Object object, Supplier<T> notNullSupplier,
                                                Supplier<? extends RuntimeException> nullSupplier) {
        if (Objects.nonNull(object)) {
            return notNullSupplier.get();
        } else {
            throw nullSupplier.get();
        }
    }

    /**
     *
     * @param object 判断
     * @param exceptionSupplier 异常supplier
     */
    public static void throwIfNull(Object object, Supplier<? extends RuntimeException> exceptionSupplier) {
        if (Objects.isNull(object)) {
            throw exceptionSupplier.get();
        }
    }


    /**
     * @param object    对象
     * @param nullSupplier 为空时执行
     * @param defaultVal   不为空时返回
     * @return 返回
     */
    public static <T> T getIfNull(Object object, Supplier<T> nullSupplier, T defaultVal) {
        if (Objects.isNull(object)) {
            return nullSupplier.get();
        } else {
            return defaultVal;
        }
    }



    /**
     * @param object    对象
     * @param nullRunnable 为空时执行
     */
    public static void doIfNull(Object object, ByRunnable nullRunnable) {
        if (Objects.isNull(object)) {
            nullRunnable.run();
        }
    }

    public static void main(String[] args) {
        Set<String> set = null;
        doIfNotNull(set, () -> set.size());//正常执行
        doIfNotNull(set, set::size);//NullPointerException
        getIfNotNullOrElse(set, () -> set.isEmpty(), () -> Boolean.FALSE);//正常执行
        getIfNotNullOrElse(set, set::isEmpty, () -> Boolean.FALSE);//NullPointerException
    }
}
